//
// ppu.c
//
// CSE 420
// Project 4 : Part 1
// Authors: Colin Hofman, Alan Tu, Adam Fairfield
//

// System includes
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <ctype.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <libspe2.h>
#include <cbe_mfc.h>
#include <pthread.h>
#include <unistd.h>
#include <math.h>

// Local includes
#include "common.h"

// Global variables
int matrixA_InPPE[NUM_OF_ROWS][NUM_OF_COLS];
int matrixB_InPPE[NUM_OF_ROWS][NUM_OF_COLS];
int matrixC_InPPE[NUM_OF_ROWS][NUM_OF_COLS];

// Forward function declarations
void initMatrices();
void printMatrices();

//
// Main ppu function.
//
// @param   int   argc     Argument count
//          char* argv[]   Argument list
// @return  int            Return status
//
int main(int argc, char *argv[])
{
	int sum;
   
  // Initialize A and B with random values
	initMatrices();

#ifdef TIMING
	long unsigned int start_t, end_t;
	start_t = __mftb();
#endif

	// Multiply matrices: A X B = C
	for (int row = 0; row < NUM_OF_ROWS; row++)
	{
		for (int col = 0; col < NUM_OF_COLS; col++)
		{
			sum = 0;
			for (int i = 0; i < NUM_OF_ROWS; i++)
			{
				sum += matrixA_InPPE[row][i] * matrixB_InPPE[i][col];
			}
			matrixC_InPPE[row][col] = sum;
		}
	}

#ifdef TIMING
  end_t = __mftb();
  printf("\n\n\nTotal time used by SPE: %f us\n\n\n", (float)((end_t - start_t) / 79.8));
#endif

  // Print the result of multiplying AxB
	//printMatrices();

	return 0;
}

// 
// Initialize matrices A and B with random integers from (0, 100].
//
void initMatrices()
{
	for (int row = 0; row < NUM_OF_ROWS; row++)
	{
		for (int col = 0; col < NUM_OF_COLS; col++)
		{
			matrixA_InPPE[row][col] = random() % 100;
			matrixB_InPPE[row][col] = random() % 100;
		}
	}
}

//
// Print the A and B input matrices, and the resulting C matrix.
//
void printMatrices()
{
	int row, col;

	printf("Matrix A:\n");
	for(row = 0; row < NUM_OF_ROWS; row++)
	{
		for(col = 0; col < NUM_OF_COLS; col++)
		{
			printf("%8d", matrixA_InPPE[row][col]);
		}
		printf("\n");
	}

	printf("Matrix B:\n");
	for(row = 0; row < NUM_OF_ROWS; row++)
	{
		for(col = 0; col < NUM_OF_COLS; col++)
		{
			printf("%8d", matrixB_InPPE[row][col]);
		}
		printf("\n");
	}

	printf("Matrix C:\n");
	for(row = 0; row < NUM_OF_ROWS; row++)
	{
		for(col = 0; col < NUM_OF_COLS; col++)
		{
			printf("%8d", matrixC_InPPE[row][col]);
		}
		printf("\n");
	}
}